package br.com.cast.scc.pages.veiculo;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;

import br.com.cast.scc.excecoes.PlacaJaInformadaException;
import br.com.cast.scc.model.DominioTipoVeiculo;
import br.com.cast.scc.model.Veiculo;
import br.com.cast.scc.service.TipoVeiculoService;
import br.com.cast.scc.service.VeiculoService;

public class CadastrarVeiculoForm extends Form<Veiculo> {

	private static final long serialVersionUID = 1L;
	
	@SpringBean(name = "tipoVeiculoServiceImpl")
	private TipoVeiculoService tipoVeiculoService;
	
	@SpringBean(name = "veiculoServiceImpl")
	private VeiculoService veiculoService;

	private WebMarkupContainer panelCamposTerrestres;
	
	private WebMarkupContainer panelCamposFluviais;

	private DropDownChoice<DominioTipoVeiculo> tipoVeiculo;

	public CadastrarVeiculoForm(String id) {
		
		super(id, new CompoundPropertyModel<>(
				new Veiculo()));
		
		add(new FeedbackPanel("msgErro"));
		
		criaPaineisCampos();
		
		criaCampoTipoVeiculo();
		
		criaCampoNuEmbarcacao();
		
		criaCampoRntrc();
		
		FormComponent<String> placa1 = 
				criaCampoPlaca("placa1")
				.setRequired(true);
		
		FormComponent<String> placa2 =
			criaCampoPlaca("placa2");
		
		FormComponent<String> placa3 =
			criaCampoPlaca("placa3");
		
		FormComponent<String> placa4 =
			criaCampoPlaca("placa4");
		
		add(new PlacasIguaisValidator(
			placa1
			, placa2
			, placa3
			, placa4
		));
		
		criaCampoEndAcesso();
		
		criaCampoLoginAcesso();
		
		criaCampoSenhaAcesso();
		
		addBehaviorVisibilidade();
		
		add(panelCamposTerrestres
		  , panelCamposFluviais);
		
	}
	
	@Override
	protected void onSubmit() {
		
		Veiculo veiculo = (Veiculo) getDefaultModelObject();
		
		try {
			String msg = "Inclusão realizada com sucesso!";
			if (veiculo.getCodigo() != null) {
				msg = "Dados alterados com sucesso!";
			}
			
			veiculoService.salvar(veiculo);
			
			ConsultaVeiculoIndexPage index = 
					new ConsultaVeiculoIndexPage();
			index.success(msg);
			setResponsePage(index);
		} catch (PlacaJaInformadaException e) {
			error(e.getMessage());
		}
		
	}

	private void criaCampoSenhaAcesso() {
		add(new RequiredTextField<>("senhaAcesso"));
	}

	private void criaCampoLoginAcesso() {
		add(new RequiredTextField<>("loginAcesso"));
	}

	private void criaCampoEndAcesso() {
		add(new RequiredTextField<>("endAcessoLink"));
	}

	private void criaCampoRntrc() {
		panelCamposTerrestres.add(new RequiredTextField<>("rntrc"));
	}

	private TextField<String> criaCampoPlaca(String id) {
		TextField<String> placa = new TextField<>(id);
		panelCamposTerrestres.add(placa);
		return placa;
	}

	private void criaCampoNuEmbarcacao() {
		panelCamposFluviais.add(
			new RequiredTextField<>("nuEmbarcacao"));
	}

	private void criaCampoTipoVeiculo() {
		IChoiceRenderer<DominioTipoVeiculo> renderer = 
				new ChoiceRenderer<>("descricao");
		
		tipoVeiculo = new DropDownChoice<DominioTipoVeiculo>(
				"tpVeiculo", 
				tipoVeiculoService.consultaTodos(), 
				renderer);
		
		tipoVeiculo.setRequired(true);
		
		tipoVeiculo.add(new AjaxFormComponentUpdatingBehavior("change") {
			
			private static final long serialVersionUID = 1L;

			@Override
			protected void onUpdate(AjaxRequestTarget target) {
				DominioTipoVeiculo tipo = tipoVeiculo.getModelObject();
				
				boolean isTerrestre = tipo.getCodigo()
					.equals(DominioTipoVeiculo.COD_TERRESTRE);
				
				panelCamposTerrestres.setVisible(isTerrestre);
				panelCamposFluviais.setVisible(!isTerrestre);
				
				target.add(panelCamposTerrestres
						, panelCamposFluviais);
			}
		});
		
		//desabilita o campo caso seja o fluxo de alteração
		tipoVeiculo.add(new Behavior() {
			private static final long serialVersionUID = 1L;

			@Override
			public void onConfigure(Component component) {
				Veiculo veiculo = (Veiculo) 
						CadastrarVeiculoForm.this
							.getDefaultModelObject();
				
				//fica habilitado somente se for fluxo de inclusão
				//, ou seja, codigo == null 
				component.setEnabled(
						veiculo.getCodigo() == null);
			}
			
		});
		
		add(tipoVeiculo);
	}

	/**
	 * Paineis que são utilizados como critério de visibilidade
	 * dos campos
	 */
	private void criaPaineisCampos() {
		
		panelCamposTerrestres = 
				new WebMarkupContainer("panelCamposTerrestres");
		panelCamposTerrestres.setVisible(false);
		panelCamposTerrestres
			.setOutputMarkupPlaceholderTag(true);
		
		panelCamposFluviais = 
				new WebMarkupContainer("panelCamposFluviais");
		panelCamposFluviais.setVisible(false);
		panelCamposFluviais
			.setOutputMarkupPlaceholderTag(true);
		
	}

	private void addBehaviorVisibilidade() {
		ControleVisbilidadeCamposVeiculo behavior =
				new ControleVisbilidadeCamposVeiculo(
						tipoVeiculo, panelCamposTerrestres, panelCamposFluviais);
		
		panelCamposTerrestres.add(behavior);
		panelCamposFluviais.add(behavior);
	}

}
